package model.visibility;

import java.util.List;

import model.map.GameTile;
import model.mapping.ItemMapping;
import model.mapping.PlayableMapping;
import model.mapping.ResourceMapping;
import model.playable.RallyPoint;
import model.playable.structure.Structure;
import model.playable.unit.Colonist;
import model.playable.unit.Explorer;
import model.playable.unit.Melee;
import model.playable.unit.Ranged;
import model.playable.unit.Unit;
import model.playable.unit.Worker;
import model.playable.unit.Vehicle;

public class VisibleTile implements PlayableVisitor
{
	private PlayableMapping playableMapping = PlayableMapping.getPlayableMapping();
	private ResourceMapping resourceMapping = ResourceMapping.getResourceMapping();
	private ItemMapping itemMapping = ItemMapping.getItemMapping();
	
	private int numWorkers;
	private int numColonists;
	private int numExplorers;
	private int numRangeds;
	private int numMelees;
	private int numVehicles;
	private int numRallys;
	private String structureType;
	private Visibility visibility;
	private int amountFood;
	private int amountOre;
	private int amountEnergy;
	private boolean resourcesRevealed;
	private String itemType;
	
	private GameTile tile;
	
	public VisibleTile(GameTile tile)
	{
		this.tile = tile;
		
		numWorkers = numColonists = numExplorers = numRangeds = numMelees = numVehicles = numRallys = 0;
		structureType = "";
		itemType = "";
		visibility = Visibility.NONVISIBLE;
		amountFood = amountOre = amountEnergy = -1;
		resourcesRevealed = false;
		
	}
	
	public void setVisible()
	{
		visibility = Visibility.VISIBLE;
	}
	
	public void setNonVisible()
	{
		visibility = Visibility.NONVISIBLE;
	}
	
	public void revealResources()
	{
		resourcesRevealed = true;
	}
	
	public void update()
	{
		clear();
		
		List<Unit> units = playableMapping.getUnitsOn(tile);
		Structure structure = playableMapping.getStructureOn(tile);
		List<Worker> workers = playableMapping.getWorkersOn(tile);
		
		for (Unit u : units)
			u.accept(this);
		
		if (structure != null)
			structure.accept(this);
		
		for (Worker w : workers)
			w.accept(this);
		
		if (resourcesRevealed)
		{
			amountFood = resourceMapping.getFood(tile);
			amountOre = resourceMapping.getOre(tile);
			amountEnergy = resourceMapping.getEnergy(tile);
		}
		
		if (itemMapping.isOccupied(tile))
			itemType = itemMapping.getItemTypeOn(tile);
		else
			itemType = "";
		
		
	}
	
	private void clear()
	{
		numWorkers = numColonists = numExplorers = numRangeds = numMelees = numVehicles = numRallys = 0;
		structureType = "";
	}
	
	public void visitColonist(Colonist u)
	{
		//System.out.println("Visiting Colonist");
		numColonists++;
	}

	public void visitExplorer(Explorer u)
	{
		//System.out.println("Visiting Explorer");
		numExplorers++;
	}

	public void visitMelee(Melee u) 
	{
		//System.out.println("Visiting Melee");
		numMelees++;
	}

	public void visitRallyPoint(RallyPoint u) 
	{
		//System.out.println("Visiting rallyPoint");
		numRallys++;

	}

	public void visitRanged(Ranged u) 
	{
		//System.out.println("Visiting Ranged");
		numRangeds++;
	}

	public void visitStructure(Structure s) 
	{
		//System.out.println("Visiting Structure");
		structureType = s.toString();
	}

	public void visitWorker(Worker u) 
	{
		//System.out.println("Visiting worker");
		numWorkers++;
	}

	public void visitVehicle(Vehicle u) 
	{
		//System.out.println("Visiting Vehicle");
		numVehicles++;		
	}

	public GameTile getTile()
	{
		return tile;
	}

	public void build(TileBuilder builder)
	{
		if (resourcesRevealed)
		{
			builder.setFoodAmount(amountFood);
			builder.setOreAmount(amountOre);
			builder.setEnergyAmount(amountEnergy);
		}
		
		builder.setVisibility(visibility);
		
		builder.setItemType(itemType);
		
		builder.setStructure(structureType);
		
		builder.setNumberColonists(numColonists);
		builder.setNumberExplorers(numExplorers);
		builder.setNumberMelees(numMelees);
		builder.setNumberRangeds(numRangeds);
		builder.setNumberVehicles(numVehicles);
		builder.setNumberWorkers(numWorkers);
		builder.setNumberRallyPoints(numRallys);
		
	}

}
